/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */
import DragTable from '../dragTable';
import ProTable, { ActionType, ProTableProps } from '@ant-design/pro-table';
import type { ParamsType } from '@ant-design/pro-provider';
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import { isFunction } from 'lodash';
import TableOperateContext, { OperateFun } from './_utils/context';
import { FormInstance } from 'antd';
import { useCache } from './_utils/cache';

interface TablePaginationParams {
  current: number;
  pageSize: number;
}

interface ProTableExtendProps<T> {
  onOperate?: OperateFun<T>;
  name?: string;
}

const ProTableExtend = <T extends Record<string, any>, U extends ParamsType, ValueType>(
  props: ProTableProps<T, U, ValueType> & ProTableExtendProps<T>,
) => {
  const actionRef = useRef<ActionType>();
  const formRef = useRef<FormInstance>();
  const ref = useRef({ count: 1 });
  const {
    pagination: paginationProps,
    scroll: scrollProps,
    request: requestProps,
    actionRef: actionRefProps,
    formRef: formRefProps,
    onOperate,
    name,
    ...restProps
  } = props;

  const { data: cacheData, update: cacheUpdate } = useCache<TablePaginationParams & T>(
    name,
    formRef,
  );

  const pagination = useMemo(
    () => ({
      current: cacheData.current || 1,
      pageSize: 20,
      showSizeChanger: false,
      ...paginationProps,
    }),
    [paginationProps, cacheData],
  );

  const scroll = useMemo(
    () => ({
      x: 1200,
      ...scrollProps,
    }),
    [scrollProps],
  );

  useEffect(() => {
    if (actionRefProps) {
      (actionRefProps as any).current = actionRef.current;
    }
    if (formRefProps) {
      (formRefProps as any).current = formRef.current;
    }
  }, []);

  const request: ProTableProps<T, U, ValueType>['request'] = useCallback(
    (params, sort, filter) => {
      if (isFunction(requestProps)) {
        // 首次请求使用缓存合并数据；再次请求使用正常传入数据
        const mergeParams =
          ref.current.count === 1
            ? {
                ...cacheData,
                ...params,
              }
            : params;
        // 记录查询条件
        cacheUpdate(mergeParams);
        ref.current.count++;
        return requestProps(mergeParams, sort, filter).then((res) => {
          const { success } = res;
          if (!success && pagination.current > 1) {
            // 非第一页无值，退回第一页
            const reloadAndRest = actionRef.current?.reloadAndRest;
            if (isFunction(reloadAndRest)) {
              reloadAndRest();
            }
          }
          return res;
        });
      }
      return Promise.resolve({});
    },
    [pagination, cacheData],
  );

  const value = useMemo(() => ({ onOperate }), [onOperate]);

  return (
    <TableOperateContext.Provider value={value}>
      <DragTable>
        <ProTable
          rowKey='id'
          options={false}
          search={false}
          {...restProps}
          scroll={scroll}
          request={request}
          pagination={pagination}
          actionRef={actionRef}
          formRef={formRef}
        />
      </DragTable>
    </TableOperateContext.Provider>
  );
};

export default ProTableExtend;
